const util = require('util');
const debug = util.debuglog('oil-game:upgrade:remote');

const {
    getIncomeRate,    //返回当前采集收入速度算法
    getDepthNum,    //当前深度
    getDepthConsume,    //当前深度消耗
    getQualityConsume,    //当前品质消耗
    getSpreedCoinsConsume,    //当前速度消耗
    addCoins,   //金币增加
    formatCoins,    //格式化金币数量
    getLogOutCoins,   //获取离线金币数量
    cronSyncCoins,    //cron定时更新用户金币数量
    getUpgradeDate,    //获取升级相关数据
    getScaleIncomeRateByHours,    //获取相应倍数的每小时产量
    addIncomeRate,    //采集收入加速
    openDoubleRewardAction,
    getPerProduct, //开启双倍奖励
    isInDoubleAct, //判断是否开启双倍奖励
} = require('../lib/action');
const {
    initUpgradeByMongo, getLevelInfo,   // 初始化升级信息数据表
} = require('../lib/dao');
const utils = require('../../../util/utils');
const {Msg} = require('../../../util/consts');

module.exports = function (app) {
    return new Handler(app);
};
let Handler = function (app) {
    this.app = app;
};
let handler = Handler.prototype;

// 更新用户的金币数量并向用户返回
handler.cronSyncCoins = async function (uid, sid, last_login_time, last_logout_time, cb) {
    debug("uid = %s  sid = %s  更新用户的金币数量并向用户返回", uid, sid);
    try {
        //更新用户的金币数量并向用户返回
        await cronSyncCoins.call(this, uid, sid, last_login_time, last_logout_time);
        //调用回调
        utils.invokeCallback(cb);
    } catch (err) {
        debug("uid = %s  sid = %s  更新用户的金币数量并向用户返回异常 %s", uid, sid, JSON.stringify(err));
        utils.invokeCallback(cb, err);
    }
}

//产金并推送
handler.productCoins = async function (uid, frontendId, product, loginId, cb) {
    let self = this;
    try {
        //更新用户的金币数量并向用户推送
        self.app.rpcInvoke(loginId, {
            namespace: 'user',
            serverType: 'login',
            service: 'loginRemote',
            method: 'addCoins',
            args: [
                uid,
                frontendId,
                product,
                true
            ]
        }, function () {

        });

        //调用回调
        utils.invokeCallback(cb);
    } catch (err) {

        utils.invokeCallback(cb, err);
    }
}

/**
 * 关闭双倍奖励
 * @param uid
 * @param frontendId
 * @param product
 * @param loginId
 * @param cb
 * @returns {Promise<void>}
 */
handler.doubleRewardFinish = async function (uid, frontendId, loginId, cb) {
    let self = this;
    try {
        //更新用户的金币数量并向用户推送
        self.app.rpcInvoke(loginId, {
            namespace: 'user',
            serverType: 'login',
            service: 'loginRemote',
            method: 'closeDoubleReward',
            args: [
                uid,
                frontendId
            ]
        }, function () {
        });

        //调用回调
        utils.invokeCallback(cb);
    } catch (err) {

        utils.invokeCallback(cb, err);
    }
}

// 返回首页升级相关信息
handler.indexData = async function (uid, cb) {
    try {
        //获取用户升级信息，矿工名称，金币数量，深度等级，品质等级，速度等级
        let upgradeDate = await getUpgradeDate.call(this, uid);
        let {coins, depth_level, quality_level, spreed_level} = upgradeDate || {};
        //当前采集收入速度
        let incomeRate = await getIncomeRate(depth_level, quality_level, spreed_level);
        incomeRate = formatCoins(incomeRate);
        //深度消耗
        let depthConsume = getDepthConsume(depth_level);
        depthConsume = formatCoins(depthConsume);
        //品质消耗
        let qualityConsume = getQualityConsume(quality_level);
        qualityConsume = formatCoins(qualityConsume);
        //速度消耗
        let speedConsume = getSpreedCoinsConsume(spreed_level);
        speedConsume = formatCoins(speedConsume);
        //调用回调
        utils.invokeCallback(cb, null, {
            coins: coins ? formatCoins(coins) : "1",    //金币数量
            depth_level: depth_level ? depth_level : 1,    //深度等级
            quality_level: quality_level ? quality_level : 1,    //品质等级
            spreed_level: spreed_level ? spreed_level : 1,   //速度等级
            depth_num: getDepthNum(depth_level),    //深度
            incomeRate,    //当前采集收入速度
            depthConsume,   //深度消耗
            qualityConsume,   //品质消耗
            speedConsume,   //速度消耗
        });
    } catch (err) {
        console.error(err);
        utils.invokeCallback(cb, err);
    }
}

// 金币增加
handler.addCoins = async function (uid, coins, cb) {
    debug("用户 %s " + uid + " 增加金币数量 %s", uid, coins);
    try {
        //更新用户的金币数量
        await addCoins.call(this, uid, coins);
        //调用回调
        utils.invokeCallback(cb);
    } catch (err) {
        debug("用户" + uid + " 增加金币数量发生异常" + JSON.stringify(err));
        utils.invokeCallback(cb, err);
    }
}

// 初始化升级信息数据表
handler.initUpgradeByMongo = async function (uid, cb) {
    debug("用户" + uid + " 初始化升级信息数据表");
    try {
        //更新用户的金币数量并向用户返回
        await initUpgradeByMongo.call(this, uid);
        //调用回调
        utils.invokeCallback(cb);
    } catch (err) {
        debug("用户" + uid + " 初始化升级信息数据表发生异常" + JSON.stringify(err));
        utils.invokeCallback(cb, err);
    }
}

// 获取用户的离线金币和时长
handler.getLogOutCoins = async function (uid, last_login_time, last_logout_time, cb) {
    debug("uid = %s 用户获取离线金币", uid);
    try {
        //离线金币数量和有效离线时长
        let logoutCoinsInfo = await getLogOutCoins.call(this, uid, last_login_time, last_logout_time);
        //调用回调
        utils.invokeCallback(cb, null, logoutCoinsInfo);
    } catch (err) {
        debug("uid = %s 用户获取离线金币异常 %s", uid, JSON.stringify(err));
        utils.invokeCallback(cb, err);
    }
}

// 获取升级相关数据
handler.getUpgradeDate = async function (uid, cb) {
    debug("uid = %s 获取升级相关数据", uid);
    try {
        //incomeRateNum为数字格式的当前金币收集速度
        let {depth_level, quality_level, spreed_level, incomeRate, incomeRateNum} = await getUpgradeDate.call(this, uid);
        //调用回调
        utils.invokeCallback(cb, null, {depth_level, quality_level, spreed_level, incomeRate, incomeRateNum});
    } catch (err) {
        debug("uid = %s 获取升级相关数据异常 %s", uid, JSON.stringify(err));
        utils.invokeCallback(cb, err);
    }
}

// 采集收入加速
handler.addIncomeRate = async function (uid, frontendId, time, cb) {
    debug("uid = %s  time = %s  采集收入加速", uid, time);
    try {
        await addIncomeRate.call(this, uid, frontendId, time);
        //调用回调
        utils.invokeCallback(cb);
    } catch (err) {
        debug("uid = %s  采集收入加速异常", uid, JSON.stringify(err));
        utils.invokeCallback(cb, err);
    }
}

// 获取相应倍数的每小时产量
handler.getScaleIncomeRateByHours = async function (uid, scaleAry, cb) {
    debug("uid = %s 获取相应倍数的每小时产量", uid);
    try {
        let scaleIncomeRateAry = await getScaleIncomeRateByHours.call(this, uid, scaleAry);
        utils.invokeCallback(cb, null, scaleIncomeRateAry);
    } catch (err) {
        debug("uid = %s 获取相应倍数的每小时产量异常", uid, JSON.stringify(err));
        utils.invokeCallback(cb, err);
    }
}

//开启双倍奖励
handler.openDoubleReward = async function (uid, frontendId, ttl, cb) {
    let self = this;
    await openDoubleRewardAction.call(self, uid, frontendId, ttl);
    utils.invokeCallback(cb, null, null);
}


//==========新挖矿=======================//
/**
 * 获取每秒产金币
 * @param {*} uid
 */
handler.getPreProduct = async function (uid, cb) {
    let self = this;
    let userInfo = await self.app.userRemote(uid, 'get', [uid, 'user']);
    if (!userInfo) {
        throw new Error(Msg.USER_NOT_FOUND);
    }
    let level = userInfo.levelInfo ? userInfo.levelInfo : await getLevelInfo.call(self, uid);

    let productPerSec = await getPerProduct.call(self, level, uid);
    utils.invokeCallback(cb, null, productPerSec);
}

/**
 * 判断当前是否有双倍奖励
 * @param uid
 * @param cb
 * @returns {Promise<void>}
 */
handler.isInDoubleRemote = async function (uid, cb) {
    let self = this;
    let ret = await isInDoubleAct.call(self, uid);
    utils.invokeCallback(cb, null, ret);
}
